﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Slippor.Douban.Radio.Assist
{
    public class HotKey
    {
        //如果函数执行成功，返回值不为0。
        //如果函数执行失败，返回值为0。要得到扩展错误信息，调用GetLastError。

        #region KeyModifiers enum

        [Flags]
        public enum KeyModifiers
        {
            None = 0,
            Alt = 1,
            Ctrl = 2,
            Shift = 4,
            WindowsKey = 8
        }

        #endregion

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(
            IntPtr hWnd, //要定义热键的窗口的句柄
            int id, //定义热键ID（不能与其它ID重复）           
            KeyModifiers fsModifiers, //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
            Keys vk //定义热键的内容
            );

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(
            IntPtr hWnd, //要取消热键的窗口的句柄
            int id //要取消热键的ID
            );

        //定义了辅助键的名称（将数字转变为字符以便于记忆，也可不再播放此枚举而直接使用数值）
        public static bool RegisterHotKey(IntPtr hWnd, String hotKey, Command command)
        {
            return RegisterHotKey(hWnd, hotKey, (int)command);
        }


        //定义了辅助键的名称（将数字转变为字符以便于记忆，也可不再播放此枚举而直接使用数值）
        public static bool RegisterHotKey(IntPtr hWnd, String hotKey, int command)
        {
            try
            {
                String[] mkeys = hotKey.Split('+');
                KeyModifiers modifiers = KeyModifiers.None;
                Keys key = Keys.Alt;
                foreach (String mkey in mkeys)
                {
                    if (mkey == "Ctrl")
                    {
                        modifiers = modifiers | KeyModifiers.Ctrl;
                    }
                    else if (mkey == "Shift")
                    {
                        modifiers = modifiers | KeyModifiers.Shift;
                    }
                    else if (mkey == "Alt")
                    {
                        modifiers = modifiers | KeyModifiers.Alt;
                    }
                    else if (mkey == "Win")
                    {
                        modifiers = modifiers | KeyModifiers.WindowsKey;
                    }
                    else
                    {
                        key = (Keys)Enum.Parse(typeof(Keys), mkey);
                    }
                }
                if (key != Keys.Alt)
                {
                    RegisterHotKey(hWnd, command, modifiers, key);
                    return true;
                }
            }
            catch
            {
                ;
            }
            return false;
        }

        public static void InitHotKeyTextBox(TextBox textBox)
        {
            textBox.TextChanged += (sender, e) =>
                                      {
                                          var box = sender as TextBox;
                                          if (box != null)
                                              if (!String.IsNullOrEmpty(box.Text))
                                              {
                                                  if (box.Text[0] >= 'a' && box.Text[0] <= 'z' || box.Text[0] >= '0' && box.Text[0] <= '9')
                                                  {
                                                      box.Text = box.Text.Remove(0, 1);
                                                  }
                                              }
                                      };
            textBox.KeyDown += (sender, e) =>
                                  {
                                      var box = sender as TextBox;
                                      String text = String.Empty;
                                      if (e.Control)
                                      {
                                          text = text + '+' + "Ctrl";
                                      }
                                      if (e.Alt)
                                      {
                                          text = text + '+' + "Alt";
                                      }
                                      if (e.Shift)
                                      {
                                          text = text + '+' + "Shift";
                                      }
                                      if (e.Modifiers == Keys.LWin || e.Modifiers == Keys.RWin)
                                      {
                                          text = text + '+' + "Win";
                                      }
                                      if (e.KeyCode >= Keys.A && e.KeyCode <= Keys.Z || e.KeyCode > Keys.F1 && e.KeyCode <= Keys.F12 || e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9 || e.KeyCode >= Keys.BrowserBack && e.KeyCode <= Keys.MediaPlayPause || e.KeyCode >= Keys.Multiply && e.KeyCode <= Keys.Divide)
                                      {
                                          text = text + '+' + e.KeyCode;
                                      }
                                      else if (e.KeyCode >= Keys.PageUp && e.KeyCode <= Keys.Help)
                                      {
                                          text = text + '+' + e.KeyCode;
                                      }
                                      text = text.TrimStart('+');
                                      if (box != null) box.Text = text;
                                      e.Handled = true;
                                  };
        }
    }
}